package widget.listview;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;

import com.dfhz.ken.zermall.R;


/**
 * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
 * 滑动隐藏头部
 *
 * 
 */
public class FadingRefreshLayout extends SwipeRefreshLayout implements
		OnScrollListener {

	private LinearLayout mActionBar;

	private Drawable mBgDrawable;

	private ImageView fadingBar;

	private int fadingHeight; // 可隐藏的控件高度
	private int oldY;
	private int fadingOffset;

	public static final int ALPHA_START = 20;
	public static final int ALPHA_END = 255;

	/**
	 * 滑动到最下面时的上拉操作
	 */
	private int mTouchSlop;
	/**
	 * listview实例
	 */
	private ListView mListView;

	/**
	 * 上拉监听器, 到了最底部的上拉加载操作
	 */
	private OnLoadListener mOnLoadListener;
	/**
	 * 上下滑的监听器
	 */
	private OnScrollListener mOnScrollListener;

	/**
	 * ListView的加载中footer
	 */
	private View mListViewFooter;

	/**
	 * 按下时的y坐标
	 */
	private int mYDown;
	/**
	 * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉
	 */
	private int mLastY;
	/**
	 * 是否在加载中 ( 上拉加载更多 )
	 */
	private boolean isLoading = false;


	// 均匀旋转动画
	private RotateAnimation refreshingAnimation;
	View loadingView;

	/**
	 * @param context
	 */
	public FadingRefreshLayout(Context context) {
		this(context, null);
	}

	public FadingRefreshLayout(Context context, AttributeSet attrs) {
		super(context, attrs);

		mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 16;

		mListViewFooter = LayoutInflater.from(context).inflate(
				R.layout.listview_footer, null, false);
		loadingView = mListViewFooter.findViewById(R.id.loading_icon);
		refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
				context, R.anim.rotating);
		// 添加匀速转动动画
		LinearInterpolator lir = new LinearInterpolator();
		refreshingAnimation.setInterpolator(lir);
	}

	@Override
	protected void onLayout(boolean changed, int left, int top, int right,
			int bottom) {
		super.onLayout(changed, left, top, right, bottom);

		// 初始化ListView对象
		if (mListView == null) {
			getListView();
		}
	}

	/**
	 * 获取ListView对象
	 */
	private void getListView() {
		int childs = getChildCount();
		if (childs > 0) {
			View childView = getChildAt(0);
			if (childView instanceof ListView) {
				mListView = (ListView) childView;
				// 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载
				mListView.setOnScrollListener(this);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean dispatchTouchEvent(MotionEvent event) {
		final int action = event.getAction();
		// final int pointerIndex = MotionEventCompat.getActionIndex(event);
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			// 按下
			mYDown = (int) event.getRawY();
			mLastY = (int) event.getRawY();
			// mYDown = MotionEventCompat.getX(event, pointerIndex);

			oldY = (int) event.getY();
			break;

		case MotionEvent.ACTION_MOVE:
			// 移动
			mLastY = (int) event.getRawY();

			int scrollY = getScrollY();
			int y = (int) event.getY();
			int deltaY = y - oldY;

			int willScrollY = scrollY - deltaY;//view的顶部超出屏幕的距离，当做公式

			if (willScrollY > fadingHeight)
			{// 不做操作颜色保持不变
				// willScrollY = fadingHeight;
			}
			else
			{// 颜色渐变
				updateActionBarAlpha(willScrollY * (ALPHA_END - ALPHA_START)
						/ fadingHeight + ALPHA_START);
			}

			if (willScrollY < 0) {
				willScrollY = 0;
			}

			scrollTo(0, willScrollY);
			oldY = y;
			break;

		case MotionEvent.ACTION_UP:
			// 抬起
			if (canLoad()) {
				loadData();
			}
			break;
		default:
			break;
		}

		return super.dispatchTouchEvent(event);
	}
/*
	@SuppressLint("ClickableViewAccessibility")
	@Override
	public boolean onTouchEvent(MotionEvent ev) {

		switch (ev.getAction()) {
			case MotionEvent.ACTION_DOWN:
				oldY = (int) ev.getY();
				break;
			case MotionEvent.ACTION_MOVE:
				int scrollY = getScrollY();
				int y = (int) ev.getY();
				int deltaY = y - oldY;

				int willScrollY = scrollY - deltaY;

				if (willScrollY > fadingHeight)
				{// 不做操作颜色保持不变
					// willScrollY = fadingHeight;
				}
				else
				{// 颜色渐变
					updateActionBarAlpha(willScrollY * (ALPHA_END - ALPHA_START)
							/ fadingHeight + ALPHA_START);
				}

				if (willScrollY < 0) {
					willScrollY = 0;
				}

				scrollTo(0, willScrollY);
				oldY = y;

				break;
			case MotionEvent.ACTION_UP:
				break;
		}

		return true;
	}*/

	/**
	 * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.
	 * 
	 * @return
	 */
	private boolean canLoad() {
		return isBottom() && !isLoading && isPullUp();
	}

	/**
	 * 判断是否到了最底部
	 */
	private boolean isBottom() {

		if (mListView != null && mListView.getAdapter() != null) {
			return mListView.getLastVisiblePosition() == (mListView
					.getAdapter().getCount() - 1);
		}
		return false;
	}

	/**
	 * 是否是上拉操作
	 * 
	 * @return
	 */
	private boolean isPullUp() {
		// System.out.println("mYDown:"+mYDown+"mLastY:"+mLastY+"mTouchSlop:"+mTouchSlop);
		// System.out.println("mYDown - mLastY:"+(mYDown -
		// mLastY)+"mTouchSlop:"+mTouchSlop);
		return (mYDown - mLastY) >= mTouchSlop;
	}
	/**
	 * 是否是下拉操作
	 * 
	 * @return
	 */
	private boolean isPullDown() {
		return (mYDown - mLastY) <= -100;
	}
	/**
	 * 是否是上拉操作
	 * 
	 * @return
	 */
	private boolean isPullUp2() {
		return (mYDown - mLastY) >= 100;
	}

	/**
	 * 如果到了最底部,而且是上拉操作.那么执行onLoad方法
	 */
	private void loadData() {
		if (mOnLoadListener != null) {
			// 设置状态
			setLoading(true);
			//
			mOnLoadListener.onLoad();
		}
	}

	/**
	 * @param loading
	 */
	public void setLoading(boolean loading) {
		isLoading = loading;
		if (isLoading) {
			mListView.addFooterView(mListViewFooter);
			loadingView.startAnimation(refreshingAnimation);
		} else {
			try {
				mListView.removeFooterView(mListViewFooter);
				loadingView.clearAnimation();
			}catch (Exception e){
				e.printStackTrace();
			}

			mYDown = 0;
			mLastY = 0;
		}
	}

	/**
	 * @param loadListener
	 */
	public void setOnLoadListener(OnLoadListener loadListener) {
		mOnLoadListener = loadListener;
	}

	/**
	 * @param,loadListener
	 */
	public void setOnScrollListener(OnScrollListener scrollListener) {
		mOnScrollListener = scrollListener;
	}

	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {

	}

	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// 滚动时到了最底部也可以加载更多
		if (canLoad()) {
			loadData();
		}

		if (mOnScrollListener != null) {
			if(firstVisibleItem > 0){
				mOnScrollListener.downScroll();
			}else{
				mOnScrollListener.upScroll();
			}
		}
/*		if (mOnScrollListener != null) {
			if(isPullUp2()){
				mOnScrollListener.downScroll();
			}
			else if(isPullDown()){
				mOnScrollListener.upScroll();
			}
			mLastY = mYDown;
			
		}
*/	}

	/**
	 * 加载更多的监听器
	 * 
	 * @author mrsimple
	 */
	public static interface OnLoadListener {
		public void onLoad();
	}

	/**
	 * 判断滑动的监听器
	 * 
	 * @author mrsimple
	 */
	public static interface OnScrollListener {
		public void downScroll();

		public void upScroll();
	}

	/**
	 * 一下是滑动隐藏头部所用的方法
	 */
	@Override
	protected void onFinishInflate() {
		super.onFinishInflate();

//		fadingBar = (ImageView) findViewById(R.id.fading_bar);
	}

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//		fadingHeight = fadingBar.getMeasuredHeight() - fadingOffset;
		fadingHeight = 400;
	}

	public void bindingActionBar(LinearLayout actionBar) {
		mActionBar = actionBar;
	}

	@SuppressWarnings("deprecation")
	public void setActionBarBgDrawable(Drawable bgDrawable) {
		if (mActionBar == null) {
			try {
				throw new Exception(
						"Please try to binding the actionBar before set it's background.");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		mBgDrawable = bgDrawable;
		mBgDrawable.setAlpha(ALPHA_START);
		mActionBar.setBackgroundDrawable(mBgDrawable);
	}

	@SuppressWarnings("deprecation")
	public void setActionBarAlpha(int alpha) throws Exception {
		if (mActionBar == null || mBgDrawable == null) {
			throw new Exception(
					"acitonBar is not binding or bgDrawable is not set.");
		}

		mBgDrawable.setAlpha(alpha);
		mActionBar.setBackgroundDrawable(mBgDrawable);
	}

	void updateActionBarAlpha(int alpha) {
		try {
			setActionBarAlpha(alpha);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setFadingOffset(int height) {
		fadingOffset = height;
	}
}
